package com.axinfu.util.db;

import java.math.BigDecimal;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * HandleJavaType
 *
 * @author ZJN
 * @since 2022/5/20
 */
public class HandleJavaType {

    public static final Map<Integer, String> TYPE_MAPPING = new HashMap<Integer, String>() {{
        put(Types.BIT, Boolean.class.getName());
        put(Types.TINYINT, Byte.class.getName());
        put(Types.SMALLINT, Short.class.getName());
        put(Types.INTEGER, Integer.class.getName());
        put(Types.BIGINT, Long.class.getName());
        put(Types.FLOAT, Double.class.getName());
        put(Types.REAL, Float.class.getName());
        put(Types.DOUBLE, Double.class.getName());
        put(Types.NUMERIC, BigDecimal.class.getName());
        put(Types.DECIMAL, BigDecimal.class.getName());
        put(Types.CHAR, String.class.getName());
        put(Types.VARCHAR, String.class.getName());
        put(Types.LONGVARCHAR, String.class.getName());
        put(Types.DATE, Date.class.getName());
        put(Types.TIME, Date.class.getName());
        put(Types.TIMESTAMP, Date.class.getName());
        put(Types.BINARY, "byte[]");
        put(Types.VARBINARY, "byte[]");
        put(Types.LONGVARBINARY, "byte[]");
        put(Types.NULL, Object.class.getName());
        put(Types.OTHER, Object.class.getName());
        put(Types.JAVA_OBJECT, Object.class.getName());
        put(Types.DISTINCT, Object.class.getName());
        put(Types.STRUCT, Object.class.getName());
        put(Types.ARRAY, Object.class.getName());
        put(Types.BLOB, "byte[]");
        put(Types.CLOB, String.class.getName());
        put(Types.REF, Object.class.getName());
        put(Types.DATALINK, Object.class.getName());
        put(Types.BOOLEAN, Boolean.class.getName());
        put(Types.ROWID, String.class.getName());
        put(Types.NCHAR, String.class.getName());
        put(Types.NVARCHAR, String.class.getName());
        put(Types.LONGNVARCHAR, String.class.getName());
        put(Types.NCLOB, String.class.getName());
        put(Types.SQLXML, String.class.getName());
        put(Types.REF_CURSOR, Object.class.getName());
        put(Types.TIME_WITH_TIMEZONE, LocalTime.class.getName());
        put(Types.TIMESTAMP_WITH_TIMEZONE, LocalDateTime.class.getName());
    }};

    public static final Map<String, String> JAVA_TYPE_MAPPING = new HashMap<String, String>(3) {{
        put(LocalDateTime.class.getName(), Date.class.getName());
        put(LocalDate.class.getName(), Date.class.getName());
        put(LocalTime.class.getName(), Time.class.getName());
        put(Double.class.getName(), BigDecimal.class.getName());
        put(Float.class.getName(), BigDecimal.class.getName());
    }};

    /**
     * 获取javatype
     *
     * @param rsmd   rsmd
     * @param column column
     * @return String
     * @throws SQLException SQLException
     */
    public String handler(ResultSetMetaData rsmd, int column) throws SQLException {
        int type = rsmd.getColumnType(column);
        String javaType = TYPE_MAPPING.get(type);
        String colClassName = rsmd.getColumnClassName(column);
        if (isConvertLocalTime() && JAVA_TYPE_MAPPING.containsKey(colClassName)) {
            javaType = JAVA_TYPE_MAPPING.get(colClassName);
        }
        return javaType;
    }

    /**
     * 是否转换本地时间
     *
     * @return boolean
     */
    public boolean isConvertLocalTime() {
        return true;
    }
}
